package timing.ukulele.third.msgChannel.handle.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayOpenAppMiniTemplatemessageSendModel;
import com.alipay.api.request.AlipayOpenAppMiniTemplatemessageSendRequest;
import com.google.common.base.Throwables;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import timing.ukulele.third.config.AlipayClientSingleton;
import timing.ukulele.third.dictionary.msg.MsgChannelType;
import timing.ukulele.third.msgChannel.handle.BaseHandler;
import timing.ukulele.third.msgChannel.model.RecallTaskInfo;
import timing.ukulele.third.msgChannel.model.SendTaskInfo;
import timing.ukulele.third.msgChannel.model.account.AlipayMiniProgramAccount;
import timing.ukulele.third.msgChannel.model.content.AlipayMiniProgramContentModel;
import timing.ukulele.third.msgChannel.param.HandleMessageBaseResponse;
import timing.ukulele.third.msgChannel.utils.AccountUtils;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 支付宝小程序发送订阅消息
 * @author zh
 */
@Component
@Slf4j
public class AlipayMiniProgramAccountHandler extends BaseHandler {

    @Autowired
    private AccountUtils accountUtils;

    public AlipayMiniProgramAccountHandler() {
        channelCode = MsgChannelType.ALIPAY_MINI_PROGRAM.getCode();
    }

    @Override
    public HandleMessageBaseResponse send(SendTaskInfo sendTaskInfo) {
        // 构造返回值
        HandleMessageBaseResponse result = new HandleMessageBaseResponse();
        // 获取支付宝小程序发送消息内容
        AlipayMiniProgramContentModel contentModel = (AlipayMiniProgramContentModel) sendTaskInfo.getContentModel();
        try {
            // 获取支付宝小程序账号信息
            AlipayMiniProgramAccount miniProgramAccount = accountUtils.getAccountById(
                    sendTaskInfo.getSendAccountId(), AlipayMiniProgramAccount.class);
            // 初始化AlipayClient
            AlipayClient client = AlipayClientSingleton.getSingleton(miniProgramAccount);
            AlipayOpenAppMiniTemplatemessageSendRequest request = assembleReq(sendTaskInfo.getReceiver(), contentModel);
            // 发送消息
            client.execute(request);
            result.setHandleFlag(true);
        } catch (Exception e) {
            log.error("AlipayMiniProgramAccountHandler#handler fail:{},params:{}",
                    Throwables.getStackTraceAsString(e), JSON.toJSONString(sendTaskInfo));
            result.setHandleFlag(false);
        }
        return result;
    }

    /**
     * 组装模板消息的参数
     */
    private AlipayOpenAppMiniTemplatemessageSendRequest assembleReq(Set<String> receiver,
                                                                          AlipayMiniProgramContentModel alipayMiniProgramContentModel) {
        // SendMessageDirectAction做了处理，所以这里只回有一条数据
        String toUserId = CollUtil.getFirst(receiver.iterator());
        AlipayOpenAppMiniTemplatemessageSendRequest request = new AlipayOpenAppMiniTemplatemessageSendRequest();
        AlipayOpenAppMiniTemplatemessageSendModel model = new AlipayOpenAppMiniTemplatemessageSendModel();
        //兼容新旧用户ID
        if (toUserId.startsWith("2088")) {
            model.setToUserId(toUserId);
        } else {
            model.setToOpenId(toUserId);
        }
        model.setToUserId(toUserId);
        model.setUserTemplateId(alipayMiniProgramContentModel.getTemplateId());
        model.setPage(alipayMiniProgramContentModel.getPage());
        model.setData(getAlipayMiniProgramParam(alipayMiniProgramContentModel.getParamMap()));
        request.setBizModel(model);
        return request;
    }

    /**
     * 构建小程序订阅消息可变参数
     *
     * @param
     * @return AlipayMiniProgramParam
     */
    private String getAlipayMiniProgramParam(Map<String, String> data) {
        Map<String, Map<String, String>> newMap = data.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> {
                            Map<String, String> valueMap = new HashMap<>(1);
                            valueMap.put("value", entry.getValue());
                            return valueMap;
                        }
                ));
        return JSON.toJSONString(newMap);
    }

    /**
     * @param recallTaskInfo
     */
    @Override
    public HandleMessageBaseResponse recall(RecallTaskInfo recallTaskInfo) {
        // 未实现 or 渠道不支持
        return HandleMessageBaseResponse.builder().handleFlag(true).build();
    }

}
